import { h, ref } from "vue";
import type {
  UploadFile,
  UploadFiles,
  UploadRequestOptions
} from "element-plus";
import { message } from "@/utils/message";
import {
  deleteFileAttachmentById,
  getBusinessIdList,
  uploadAttachments
} from "@/api/upload";
import type { UploadProps } from "@/components/ReUpload/utils/types";
import { addDialog } from "@/components/ReDialog/index";
import { deviceDetection } from "@pureadmin/utils";
import refilePreview from "@/components/RefilePreview/src/index.vue";

export default function useUploadHook(props: UploadProps) {
  const uploadRef = ref(); // 组件实例
  const files = ref<UploadFile[]>(props.fileList || []); // 文件列表
  const multiFile = ref<boolean>(props.multiFile); // 多个文件
  const businessId = ref<number>(props.businessId); // 业务主键
  const tableName = ref<string>(props.tableName); // 数据库表名
  const filePath = ref<string>(props.filePath); // 文件路径
  const limit = ref<number>(props.limit); // 允许上传文件数量
  const disabled = ref<boolean>(props.disabled); // 禁用
  const fileSize = ref<number>(props.fileSize); // 文件大小
  const tip = ref<string>(props.tip); // 提示文字
  const accept = ref<string>(props.accept); // 允许上传文件类型

  /**
   * 文件改变
   * @param file
   * @param fileList
   */
  function changeFileLength(file: UploadFile, fileList: UploadFiles) {
    files.value = fileList;
    const fileSuffix = file.name.substring(file.name.lastIndexOf(".") + 1);
    const acceptList = accept.value.split(",");
    const index = fileList.findIndex((item: any) => item.name === file.name);
    if (acceptList.indexOf("." + fileSuffix) === -1) {
      message(`上传文件只能是 ${accept.value}`, {
        type: "error"
      });
      if (index !== -1) {
        fileList.splice(index, 1);
      }
    } else if (file.size >= fileSize.value) {
      const gb = (file.size / fileSize.value).toFixed(4);
      message(`${file.name} 文件大小超出${gb}GB，请重新选择！`, {
        type: "error"
      });
      if (index !== -1) {
        fileList.splice(index, 1);
      }
    }
    let fileName = encodeURI(file.name); // 如果可以上传多个文件，这里需要用fileList.forEach()处理
    let newFile: File = new File([file.raw], fileName);
    (newFile as any).uid = file.uid; // new File 没有uid属性，会导致组件底层报错，这里手动加上
    (file as any).raw = newFile; // 替换file的数据
  }

  /**
   * 上传方法
   * @param data
   */
  async function upload(data: {
    businessId: number;
    tableName: string;
    filePath: string;
  }) {
    if (data) {
      if (data.businessId) {
        businessId.value = data.businessId;
      }
      if (data.tableName) {
        tableName.value = data.tableName;
      }
      if (data.filePath) {
        filePath.value = data.filePath;
      }
    }
    // 触发上传 调用配置 :http-request="uploadFile"
    // 即触发 uploadFile函数
    uploadRef.value.submit();
    // 上传完成后执行的操作 ...
  }

  /**
   * 上传文件 请求
   * @param param
   */
  async function uploadFile(param: UploadRequestOptions) {
    // 创建FormData上传
    let form = new FormData();
    form.append("file", param.file);
    form.append("businessId", String(businessId.value));
    form.append("tableName", tableName.value);
    //上传操作
    await uploadAttachments(form)
      .then(res => {
        /*上传成功处理*/
        param.onSuccess(res);
      })
      .catch(err => {
        param.onError(err);
        const index = files.value.findIndex(
          item => item.name === param.file.name
        );
        if (index !== -1) {
          files.value.splice(index, 1);
        }
      });
  }

  /**
   * 上传成功
   * @param res
   * @param file
   * @param fileList
   */
  function handleFileSuccess(
    res: any,
    file: UploadFile,
    fileList: UploadFiles
  ) {
    if (!res) return;
    files.value = fileList;
    message(`${file.name} 上传成功`, {
      type: "success"
    });
  }

  interface FileItem extends UploadFile {
    id: number;
    filePath: string;
  }

  /**
   * 文件预览
   * @param file
   */
  function handleFilePreview(file: FileItem) {
    addDialog({
      title: file.name,
      props: {
        id: file.id,
        type: file.raw ? "local" : "",
        fileType: file.name.split(".")[1],
        raw: file.raw || (() => new File([], "")),
        filePath: file.raw ? "" : file.filePath
      },
      hideFooter: true,
      width: "70%",
      fullscreen: deviceDetection(),
      fullscreenIcon: true,
      closeOnClickModal: false,
      contentRenderer: () => h(refilePreview)
    });
  }

  /**
   * 文件删除
   * @param file
   * @param fileList
   */
  function handleFileRemove(file: UploadFile, fileList: UploadFiles) {
    files.value = fileList;
    if (!(file as any).id) return;
    deleteFileAttachmentById({ id: (file as any).id }).then(res => {
      if (res.success === true) {
        message(`${file.name} 删除成功`, {
          type: "success"
        });
      }
    });
  }

  /**
   * 文件超出限制
   */
  function handleFileExceed() {
    message(`只能选择${limit.value}个文件，请重新选择文件！`, {
      type: "error"
    });
  }

  /**
   * 获取文件列表
   */
  async function getFiles() {
    if (!businessId.value) return;
    // 获取文件列表
    await getBusinessIdList({ businessId: businessId.value }).then(res => {
      res.data.forEach((item: UploadFile) => {
        files.value.push({
          name: (item as any).filename,
          ...item
        });
      });
    });
  }

  return {
    files,
    multiFile,
    businessId,
    tableName,
    filePath,
    limit,
    disabled,
    fileSize,
    tip,
    accept,
    uploadRef,
    uploadFile,
    handleFileSuccess,
    handleFilePreview,
    handleFileRemove,
    handleFileExceed,
    changeFileLength,
    getFiles,
    upload
  };
}
